<?php
///////////////////////////////////////////////////////////////////////////////////////////////////////
//  这个文件是 JCAT PHP框架的一部，该项目和此文件 均遵循 GNU 自由软件协议
// 
//  Copyleft 2008 JeCat.cn(http://team.JeCat.cn)
//
//
//  JCAT PHP框架 的正式全名是：Jellicle Cat PHP Framework。
//  “Jellicle Cat”出自 Andrew Lloyd Webber的音乐剧《猫》（《Prologue:Jellicle Songs for Jellicle Cats》）。
//  JCAT 是一个开源项目，它像音乐剧中的猫一样自由，你可以毫无顾忌地使用JCAT PHP框架。
//  JCAT 由中国团队开发维护，是一个国际性的项目。
//  正在使用的这个版本是：0.3.2 / SVN信息：$Id: class.JCAT_Singleton.php 1250 2009-02-07 04:53:17Z aleechou $
//
//
//
//  相关的链接：
//    [主页] http://jcat.JeCat.cn
//    [HTTP下载] http://jcat.JeCat.cn/download
//    [在线文档] http://jcat.JeCat.cn/document
//    [社区] http://jj.jecat.cn/forum-7-1.html
//  不很相关：
//    [MP3] http://www.google.cn/search?q=jellicle+songs+for+jellicle+cats+Andrew+Lloyd+Webber
//    [VCD/DVD] http://www.google.cn/search?q=CAT+Andrew+Lloyd+Webber+video
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
/*-- Project Introduce --*/


/**
 * 单件实例 统一管理器
 *
 * @author		alee
 * @access		public
 */
class JCAT_Singleton
{


	/**
	 * 创建或返回 单件实例
	 * 
	 * @access	public
	 * @param	$sClass			string	类名
	 * @param	$Paramer...		mixed	创建单件实例的参数
	 * @static
	 * @return	
	 */
	static public function GetGlobalInstance( $sClass ) 
	{
		JCAT_ASSERT::ASSERT_ISTHESE($sClass,'string',JCAT_Language::SentenceEx('参数 $sClass 必须为 string 类型。','JCAT',null)) ;
		
		// 返回已经存在的实例
		if( isset(self::$arrInstances[$sClass]) )
		{
			return self::$arrInstances[$sClass] ;
		}
		
		// 创建 新实例前 检查 是不是有效的 单件类
		if( !self::IsSingletonClass($sClass) and $sMsg=JCAT_Language::SentenceEx('参数 $sClass 不是一个有效的单件类。','JCAT',null) )
		{
			throw new JCAT_Exception( $sMsg, JCAT_Exception::MakeExceptionCode(__CLASS__,1) ) ;
		}
		
		// 创建参数
		if( func_num_args()>1 )
		{
			$arrArgs = func_get_args() ;
			array_shift($arrArgs) ;
		}
		// 无参数
		else
		{
			$arrArgs = array() ;
		}
		
		// 工厂方法
		$Factory = isset(self::$arrInstanceFactorys[$sClass])? self::$arrInstanceFactorys[$sClass]: $sClass ;
		$sFactoryMethodName = is_array($Factory)? $Factory[1]: $Factory ;
		
		// 通过构造函数
		if( $sFactoryMethodName=='__construct' or $sFactoryMethodName==$sClass )
		{
			// 无参数
			if( count($arrArgs)==0 )
			{
				self::$arrInstances[$sClass] = new $sClass() ;
			}
			
			// 有参数
			else
			{
				self::$arrInstances[$sClass] = JCAT_Global::CreateObject($sClass,$arrArgs) ;
			}
		}
		
		// 通过注册的 实例工厂
		else
		{
			self::$arrInstances[$sClass] = call_user_func_array($Factory,$arrArgs) ;
		}
	
		return self::$arrInstances[$sClass] ;
	}



	/**
	 * 检查是否单件类
	 * 
	 * @access	public
	 * @param	$sClass		string		类名
	 * @static
	 * @return	
	 */
	static public function IsSingletonClass( $sClass ) 
	{
		JCAT_ASSERT::ASSERT_ISTHESE($sClass,'string',JCAT_Language::SentenceEx('参数 $sClass 必须为 string 类型。','JCAT',null)) ;
		
		// 已注册的单件类 或  实现单件接口 的类
		return( isset(self::$arrInstanceFactorys[$sClass]) or JCAT_Global::HasImplementedTo($sClass,'JCAT_ISingleton',true) ) ;
	}



	/**
	 * 注册单件的实例工厂
	 * 
	 * @access	public
	 * @param	$sClass		string		类名
	 * @param	$Factory	callback	实例工厂
	 * @static
	 * @return	old_value
	 */
	static public function RegisterInstanceFactory( $sClass, $Factory ) 
	{
		JCAT_ASSERT::ASSERT_ISTHESE($sClass,'string',JCAT_Language::SentenceEx('参数 $sClass 必须为 string 类型。','JCAT',null)) ;
		JCAT_ASSERT::ASSERT_ISTHESE($Factory,'callback',JCAT_Language::SentenceEx('参数 $Factory 必须为有效的 callback 类型。','JCAT',null)) ;
		
		if( !class_exists($sClass) and $sMsg=JCAT_Language::SentenceEx('参数 $sClass 必须是有效的类名','JCAT',null) )
		{
			throw new JCAT_Exception( $sMsg, JCAT_Exception::MakeExceptionCode(__CLASS__,3) ) ;
		}
		

		$old_value = isset(self::$arrInstanceFactorys[$sClass])? 
						self::$arrInstanceFactorys[$sClass]:
						null ;

		self::$arrInstanceFactorys[$sClass] = $Factory ;
		return $old_value ;
	}



	/**
	 * 取消一个单件工厂的注册
	 * 
	 * @access	public
	 * @param	$sClass	string	类名
	 * @static
	 * @return	old_value
	 */
	static public function UnregisterInstanceFactory( string $sClass ) 
	{
		JCAT_ASSERT::ASSERT_ISTHESE($sClass,'string',JCAT_Language::SentenceEx('参数 $sClass 必须为 string 类型。','JCAT',null)) ;
		if( !class_exists($sClass) and $sMsg=JCAT_Language::SentenceEx('参数 $sClass 必须是有效的类名','JCAT',null) )
		{
			throw new JCAT_Exception( $sMsg, JCAT_Exception::MakeExceptionCode(__CLASS__,4) ) ;
		}

		$old_value = isset(self::$arrInstanceFactorys[$sClass])? 
						self::$arrInstanceFactorys[$sClass]:
						null ;

		unset(self::$arrInstanceFactorys[$sClass]) ;
		return $old_value ;
	}




	// 属性 ///////////////////////////////////////////////////////////////////////////////

	/**
	 * 已创建的实例
	 * 
	 * @access	private
	 * @var		array
	 * @static
	 */
	static protected $arrInstances ;

	/**
	 * 已注册的实例工厂
	 * 
	 * @access	private
	 * @var		array
	 * @static
	 */
	static protected $arrInstanceFactorys ;


}
/*macro_exception_code:4*/
?>